/*
 * Created by LiuYou on 2020/12/30.
 *
 */


#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#include "Pcb.hpp"


using std::cout;
using std::endl;
using std::queue;
using std::vector;
using std::sort;
using std::shared_ptr;
using std::make_shared;
using ProcessSchedule::Pcb;
using ProcessSchedule::ProcessState;

void simulateProcess(queue<shared_ptr<Pcb>>& readyQueue, vector<shared_ptr<Pcb>>& vector);


queue<shared_ptr<Pcb>> processSchedule(vector<shared_ptr<Pcb>>& vector, shared_ptr<Pcb>* ptr);

int main() {
    shared_ptr<Pcb> pcb1(make_shared<Pcb>("p1", 10, 2));
    shared_ptr<Pcb> pcb2(make_shared<Pcb>("p2", 3, 4));
    shared_ptr<Pcb> pcb3(make_shared<Pcb>("p3", 2, 1));
    shared_ptr<Pcb> pcb4(make_shared<Pcb>("p4", 5, 5));
    shared_ptr<Pcb> pcb5(make_shared<Pcb>("p5", 7, 3));
//    cout << pcb1->toString() << endl;
//    cout << pcb2->toString() << endl;
//    cout << pcb3->toString() << endl;
//    cout << pcb4->toString() << endl;
//    cout << pcb5->toString() << endl;
    queue<shared_ptr<Pcb>> queue;
    vector<shared_ptr<Pcb>> vector;
    shared_ptr<Pcb> headOfTheQueue(std::make_shared<Pcb>("headOfTheQueue"));
    shared_ptr<Pcb>* ptr{&headOfTheQueue};
    vector.push_back(pcb1);
    vector.push_back(pcb2);
    vector.push_back(pcb3);
    vector.push_back(pcb4);
    vector.push_back(pcb5);

    std::cout << vector.size() << std::endl;
//    std::cout << vector.empty() << std::endl;


    int value{0};


//    while (vector.empty()) {
//    while (queue.empty()) {
//    for (int i = 0; i < 32; ++i) {
    while (!vector.empty()) {
        ::queue<shared_ptr<Pcb>> readyQueue = processSchedule(vector, ptr);
        simulateProcess(readyQueue, vector);
        queue = readyQueue;
        ++value;
    }

    std::cout << "执行时间: " << value << std::endl;


    return 0;
}

queue<shared_ptr<Pcb>> processSchedule(std::vector<shared_ptr<Pcb>>& vector, shared_ptr<Pcb>* ptr) {
/*

    // 巨大的错误！！！！
    while (!vector.empty()) {
        queue.push(vector.front());
        vector.erase(vector.cbegin());
    }
    while (!queue.empty()) {
        vector.push_back(queue.front());
        queue.pop();
    }

    */



    sort(vector.begin(), vector.end(), [](const std::shared_ptr<Pcb>& lhs, const std::shared_ptr<Pcb>& rhs) -> bool {
        return lhs->getPriority() > rhs->getPriority();
    });
    cout << "===========================================================" << std::endl;
    for (auto& item : vector) {
        ptr->get()->setNext(item);
        ptr = &item;
    }
//    std::cout << "vector size: " << vector.size() << std::endl;
    ::queue<shared_ptr<Pcb>> queue;
    for (const auto& item : vector) {
        queue.push(item);
        cout << item->toString() << std::endl;
    }
//    std::cout << "vector size: " << vector.size() << std::endl;
    return std::move(queue);
}

void simulateProcess(queue<shared_ptr<Pcb>>& readyQueue, vector <shared_ptr<Pcb>>& vector) {
    cout << "======================================================================" << endl;
    std::shared_ptr<Pcb> temp(readyQueue.front());
    std::cout << "处理机执行E: " << temp->getProcessName() << std::endl;
    if (temp->getPriority() == 1) {
    } else {
        temp->setPriority(short(temp->getPriority() - 1));
    }
    if (temp->getExecuteTime() == 1) {
        temp->setProcessState(ProcessState::TERMINATED);
        // TODO 根据执行结果进行修改
        //        temp->setNext(nullptr);
    } else {
        temp->setExecuteTime(temp->getExecuteTime() - 1);
        vector.push_back(temp);
    }
    vector.erase(vector.cbegin());
//    cout << "length: " << queue.size() << endl;
    readyQueue.pop();
//    cout << "length: " << queue.size() << endl;
//    cout << temp->toString() << endl;

}



































/*
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#include "Pcb.hpp"

using std::cout;
using std::endl;
using std::queue;
using std::vector;
using std::sort;
using std::shared_ptr;
using ProcessSchedule::Pcb;
using ProcessSchedule::ProcessState;

int main() {
    shared_ptr<Pcb> pcb1(std::make_shared<Pcb>("p1", 10, 2));
    shared_ptr<Pcb> pcb2(std::make_shared<Pcb>("p2", 3, 4));
    shared_ptr<Pcb> pcb3(std::make_shared<Pcb>("p3", 2, 1));
    shared_ptr<Pcb> pcb4(std::make_shared<Pcb>("p4", 5, 5));
    shared_ptr<Pcb> pcb5(std::make_shared<Pcb>("p5", 7, 3));
    cout << pcb1->toString() << endl;
    cout << pcb2->toString() << endl;
    cout << pcb3->toString() << endl;
    cout << pcb4->toString() << endl;
    cout << pcb5->toString() << endl;
    queue<shared_ptr<Pcb>> queue;
    shared_ptr<Pcb> headOfTheQueue(std::make_shared<Pcb>("headOfTheQueue"));
    vector<shared_ptr<Pcb>> vector;
    vector.push_back(pcb1);
    vector.push_back(pcb2);
    vector.push_back(pcb3);
    vector.push_back(pcb4);
    vector.push_back(pcb5);
    sort(vector.begin(), vector.end(), [](const shared_ptr<Pcb>& lhs, const shared_ptr<Pcb>& rhs) -> bool {
        return lhs->getPriority() > rhs->getPriority();
    });
    cout << "===========================================================" << std::endl;
*/
/*    for (const auto& item : vector) {
        queue.front()->setNext(item);
        queue.push(item);
        cout << item->toString() << std::endl;
    }*//*


*/
/*    ::vector<shared_ptr<Pcb>> vector1;
    vector1.push_back(temp);
    for (const auto& item : vector) {
        vector1.back()->setNext(item);
        vector1.push_back(item);
    }

    for (const auto& item : vector1) {
        cout << item->toString() << endl;
    }
// headOfTheQueue
 *//*


    shared_ptr<Pcb>* ptr{&headOfTheQueue};
    for (auto& i : vector) {
        ptr->get()->setNext(i);
        ptr = &i;
    }
//    headOfTheQueue->setNext(vector[0]);

    for (const auto& item : vector) {
        cout << item->toString() << std::endl;
    }


    return 0;
}*/
